import { Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { formatDate } from 'src/utils'
import { Repository, Not, IsNull } from 'typeorm'
import { Staff } from '../staff/entities/staff.entity'
import { CreateTransferDto } from './dto/create-transfer.dto'
import { UpdateTransferDto } from './dto/update-transfer.dto'
import { Transfer } from './entities/transfer.entity'
import { Department } from '../department/entities/department.entity'
import { Job } from '../job/entities/job.entity'

@Injectable()
export class TransferService {
  constructor(
    @InjectRepository(Transfer) private readonly transfer: Repository<Transfer>,
    @InjectRepository(Staff) private readonly staff: Repository<Staff>,
    @InjectRepository(Department)
    private readonly department: Repository<Department>,
    @InjectRepository(Job) private readonly job: Repository<Job>
  ) {}
  async create(createTransferDto: CreateTransferDto) {
    const transfer = new Transfer()
    const staff = await this.staff.findOne({
      where: { id: createTransferDto.staffId }
    })
    const beforeDepartment = await this.department.findOne({
      where: { id: createTransferDto.beforeDepartmentId }
    })
    const afterDepartment = await this.department.findOne({
      where: { id: createTransferDto.afterDepartmentId }
    })
    const beforeJob = await this.job.findOne({
      where: { id: createTransferDto.beforeJobId }
    })
    const afterJob = await this.job.findOne({
      where: { id: createTransferDto.afterJobId }
    })
    transfer.staff = staff
    transfer.beforeDepartment = beforeDepartment
    transfer.afterDepartment = afterDepartment
    transfer.beforeJob = beforeJob
    transfer.afterJob = afterJob
    transfer.reason = createTransferDto.reason
    transfer.date = formatDate(new Date())
    transfer.remark = createTransferDto.remark
    await this.staff.update(staff.id, {
      department: afterDepartment,
      job: afterJob
    })
    return this.transfer.save(transfer)
  }

  async findAll(
    params: {
      page: number
      pageSize: number
      isDelete?: boolean
    },
    staffId?: number
  ) {
    const where = {}
    params.isDelete && (where['deleteDate'] = Not(IsNull()))
    staffId && (where['staff'] = { id: staffId })
    const data = await this.transfer.find({
      where: { ...where },
      withDeleted: params.isDelete,
      relations: [
        'staff',
        'beforeDepartment',
        'afterDepartment',
        'beforeJob',
        'afterJob'
      ],
      skip: (params.page - 1) * params.pageSize,
      take: params.pageSize
    })
    const total = await this.transfer.count({
      where: { ...where },
      relations: ['staff'],
      withDeleted: params.isDelete
    })

    const newData = data.map(item => {
      return {
        ...item,
        staff: {
          id: item.staff.id,
          name: item.staff.name
        },
        beforeDepartment: {
          id: item.beforeDepartment.id,
          name: item.beforeDepartment.name
        },
        afterDepartment: {
          id: item.afterDepartment.id,
          name: item.afterDepartment.name
        },
        beforeJob: {
          id: item.beforeJob.id,
          name: item.beforeJob.name
        },
        afterJob: {
          id: item.afterJob.id,
          name: item.afterJob.name
        }
      }
    })
    return { data: newData, total }
  }

  async findOne(id: number) {
    return await this.transfer.findOne({ where: { id } })
  }

  update(id: number, updateTransferDto: UpdateTransferDto) {
    return this.transfer.update(id, updateTransferDto)
  }

  remove(ids: number[]) {
    return this.transfer.softDelete(ids)
  }

  restore(ids: number[]) {
    return this.transfer.restore(ids)
  }
}
